package com.zone.domain.acticity.service.partake;

import com.zone.domain.acticity.model.aggregate.PartakeActivityOrderAggregate;
import com.zone.domain.acticity.model.entity.*;
import com.zone.domain.acticity.model.valobj.UserRaffleOrderStateEnum;
import com.zone.domain.acticity.repository.IActivityRepository;
import com.zone.domain.acticity.service.ActivitySupport;
import com.zone.domain.acticity.service.IActivityOrderPartakeService;
import com.zone.types.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.Validate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Objects;

/**
 * @author: zongzi
 * @description: TODO
 * @date: 2025/2/19
 */
@Slf4j
@Service
public class ActivityOrderPartakeServiceImpl implements IActivityOrderPartakeService {
    @Autowired
    private ActivitySupport activityOrderSupport;
    @Autowired
    private IActivityRepository activityRepository;


    @Override
    public UserRaffleOrderEntity partTakeActivity(ActivityOrderPartakeEntity partakeEntity) {
        // 参数校验
        Validate.notEmpty(partakeEntity.getUserId(), "用户不能为空!");
        Validate.notNull(partakeEntity.getActivityId(), "活动不能为空!");

        // 判断用户是否存在已经创建user_raffle_order
        UserRaffleOrderEntity userRaffleOrderEntity = activityRepository.queryUserRaffleOrder(partakeEntity.getUserId(), partakeEntity.getActivityId(), UserRaffleOrderStateEnum.CREATE.getCode());
        if (Objects.nonNull(userRaffleOrderEntity)) {
            log.info("存在用户参与单！userId = {}, activityId = {}", partakeEntity.getUserId(), partakeEntity.getActivityId());
            return userRaffleOrderEntity;
        }

        // 查询活动、校验活动信息
        ActivityEntity activityEntity = activityOrderSupport.queryActivity(partakeEntity.getActivityId());
        ActivityEntity.EffectResult effectResult = activityEntity.takeEffect();
        if (!effectResult.isEffect()) {
            throw new BizException(effectResult.getErrorMsg());
        }
        // 构建聚合对象
        PartakeActivityOrderAggregate aggregate = this.buildPartakeActivityOrderAggregate(partakeEntity, activityEntity);

        // 新增用户参与活动单、更新用户活动次数账户
        activityRepository.createUserRaffleOrder(aggregate);

        // 返回订单信息
        return aggregate.getUserRaffleOrderEntity();
    }

    private PartakeActivityOrderAggregate buildPartakeActivityOrderAggregate(ActivityOrderPartakeEntity partakeEntity, ActivityEntity activityEntity) {
        // 用户活动账户-总
        String userId = partakeEntity.getUserId();
        Long activityId = partakeEntity.getActivityId();
        RaffleActivityAccountEntity activityAccountEntity = activityRepository.queryActivityAccount(userId, activityId);
        if (Objects.isNull(activityAccountEntity)) {
            throw new BizException("无可用抽奖次数，参与活动失败！");
        }
        // 用户活动账户-月
        RaffleActivityAccountMonthEntity raffleActivityAccountMonth = activityRepository.queryActivityAccountMonth(userId, activityId, RaffleActivityAccountMonthEntity.currentMonth());
        if (Objects.nonNull(raffleActivityAccountMonth) && raffleActivityAccountMonth.getMonthCountSurplus() < 0) {
            throw new BizException("无可用抽奖次数（月）");
        }
        // 用户活动账户-日
        RaffleActivityAccountDayEntity raffleActivityAccountDay = activityRepository.queryActivityAccountDay(userId, activityId, RaffleActivityAccountDayEntity.currentDay());
        if (Objects.nonNull(raffleActivityAccountDay) && raffleActivityAccountDay.getDayCountSurplus() < 1) {
            throw new BizException("无可用抽奖次数（日）");
        }
        PartakeActivityOrderAggregate aggregate = new PartakeActivityOrderAggregate();
        aggregate.setUserId(userId);
        aggregate.setActivityId(activityId);
        aggregate.setActivityAccountEntity(activityAccountEntity);
        // 用户参与抽奖单
        UserRaffleOrderEntity userRaffleOrderEntity = new UserRaffleOrderEntity();
        userRaffleOrderEntity.setUserId(userId);
        userRaffleOrderEntity.setActivityId(activityId);
        userRaffleOrderEntity.setActivityName(activityEntity.getActivityName());
        userRaffleOrderEntity.setStrategyId(activityEntity.getStrategyId());
        userRaffleOrderEntity.setOrderId(RandomStringUtils.randomNumeric(12));
        userRaffleOrderEntity.setOrderTime(new Date());
        userRaffleOrderEntity.setOrderState(UserRaffleOrderStateEnum.CREATE);
        aggregate.setUserRaffleOrderEntity(userRaffleOrderEntity);
        // 用户活动账户-月
        if (Objects.nonNull(raffleActivityAccountMonth)) {
            aggregate.setExistMonth(true);
            aggregate.setRaffleActivityAccountMonth(raffleActivityAccountMonth);
        } else {
            aggregate.setExistMonth(false);
            raffleActivityAccountMonth = new RaffleActivityAccountMonthEntity();
            raffleActivityAccountMonth.setUserId(userId);
            raffleActivityAccountMonth.setActivityId(activityId);
            raffleActivityAccountMonth.setMonth(RaffleActivityAccountMonthEntity.currentMonth());
            raffleActivityAccountMonth.setMonthCount(activityAccountEntity.getMonthCount());
            raffleActivityAccountMonth.setMonthCountSurplus(activityAccountEntity.getMonthCountSurplus());
            aggregate.setRaffleActivityAccountMonth(raffleActivityAccountMonth);
        }
        // 用户活动账户-日
        if (Objects.nonNull(raffleActivityAccountDay)) {
            aggregate.setExistDay(true);
            aggregate.setRaffleActivityAccountDay(raffleActivityAccountDay);
        } else {
            aggregate.setExistDay(false);
            raffleActivityAccountDay = new RaffleActivityAccountDayEntity();
            raffleActivityAccountDay.setUserId(userId);
            raffleActivityAccountDay.setActivityId(activityId);
            raffleActivityAccountDay.setDay(RaffleActivityAccountDayEntity.currentDay());
            raffleActivityAccountDay.setDayCount(activityAccountEntity.getDayCount());
            raffleActivityAccountDay.setDayCountSurplus(activityAccountEntity.getDayCountSurplus());
            aggregate.setRaffleActivityAccountDay(raffleActivityAccountDay);
        }
        return aggregate;
    }
}
